#pragma once
#include "Epoll.h"
#include <functional>
#include <memory>
#include <queue>
#include <mutex>
#include <map>
#include <atomic>

class Connection;
using ConnectionPtr = std::shared_ptr<Connection>;
class EventLoop
{
private:
    int m_timetvl;
    int m_timeout_threshold;

    std::unique_ptr<Epoll> m_ep;
    pid_t m_thread_id;
    std::queue<std::function<void()>> m_taskqueue;
    std::mutex m_mutex;
    
    int m_wakeup_fd;
    std::unique_ptr<Channel> m_wakechannel;

    int m_timerfd;                                                             // 定时器的fd。
    std::unique_ptr<Channel> m_timerchannel;              // 定时器的Channel。
    bool m_is_mainloop; 

    std::map<int,ConnectionPtr> m_conns;
    std::mutex m_mmutex;

    std::function<void(EventLoop*)> m_epoll_timeout_callback;
    std::function<void(int)> m_timer_callback;

    std::atomic_bool m_stop;

public:
    EventLoop(bool is_mainloop,int timetvl=30,int timeout_threshold = 80);
    ~EventLoop();

    void run();
    void update_channel(Channel *channel);
    void remove_channel(Channel *channel);

    void set_epoll_timeout_callback(std::function<void(EventLoop*)> fn);

    bool is_in_loop_thread();

    void queue_in_loop(std::function<void()> fn);

    void wakeup();
    void handle_wakeup();

    void handle_timer(); 

    void add_connection(ConnectionPtr conn);

    void set_timer_callback(std::function<void(int)> fn);

    void stop();
};